Quick overview

Current status

#library(nCov2019)
library(leaflet)
library(dplyr)
library(ggplot2)
library(plotly)
library(scales)
library(xts)
library(dygraphs)
library(corrplot)
COVID<-read.csv("covid_19_data.csv")
COVID_2<-read.csv("COVID19_7-Apr.csv")

Format date:

Date<-as.Date(COVID_2$Date, format="%m/%d/%y") 

COVID_2$Date2<-Date
COVID_updated<-COVID_2 %>% filter(Date2==max(Date2))
leaflet(width = "100%") %>% 
  addProviderTiles("CartoDB.DarkMatter") %>% 
  setView(lng = 0, lat = 10, zoom = 1.5) %>% 
  addCircleMarkers(data = COVID_updated, 
                   lng = ~ Long,
                   lat = ~ Lat,
                   radius = ~ log(Confirmed+1),
                   color = rgb(218/255,65/255,56/255),
                   fillOpacity = ~ ifelse(Confirmed > 0, 1, 0),
                   stroke = FALSE,
                   label = ~ paste(Province.State,",",Country.Region, ": ", Confirmed)
                   )

Current top 10 countries:

COVID_top<-COVID_2 %>% filter(Date2==max(Date2)) %>% 
  group_by(Country.Region) %>% summarise(Total_confirmed=sum(Confirmed)) %>% 
  top_n(10,Total_confirmed) %>% arrange(desc(Total_confirmed))
plot<-ggplot(data=COVID_top
       , aes(x=Total_confirmed,y=reorder(Country.Region,Total_confirmed))) +
  geom_bar(stat ="identity",alpha=0.8,fill="firebrick3") +
  geom_text(aes(label=Total_confirmed), vjust=0.5, hjust=0.9,color="black", size=3.5) +
  scale_x_continuous(labels = comma) +
  labs(title = paste("Top 10 countries with confirmed cases as of ",max(COVID_2$Date2)),
       x = "Confirmed cases",
       y = "Country") +
  theme_minimal()

ggplotly(plot,tooltip = c("x"),width=750)

Time distribution:

COVID_2_Day<- COVID_2 %>% group_by(Date2) %>% summarise(World_confirmed=sum(Confirmed),
                                                        World_deaths=sum(Deaths),
                                                        World_recovered=sum(Recovered))


COVID_Day_confirmed_series<-xts(COVID_2_Day$World_confirmed, order.by=COVID_2_Day$Date2)
COVID_Day_deaths_series<-xts(COVID_2_Day$World_deaths, order.by=COVID_2_Day$Date2)
COVID_Day_recovered_series<-xts(COVID_2_Day$World_recovered, order.by=COVID_2_Day$Date2)

Day_summary<-cbind(COVID_Day_confirmed_series,COVID_Day_deaths_series,COVID_Day_recovered_series)
dygraph(Day_summary, main = "SARS-COV2-outbreak: Total worldwide cases", 
        xlab="Date", ylab="Total cases",width = 750) %>% 
  dySeries("COVID_Day_confirmed_series", "Total cases",drawPoints = TRUE, 
           pointSize = 3, color=rgb(53/255,116/255,199/255)) %>% 
  dySeries("COVID_Day_deaths_series", "Total deaths",drawPoints = TRUE, 
           pointSize = 3, color=rgb(189/255,55/255,48/255)) %>% 
  dySeries("COVID_Day_recovered_series", "Total recovered",drawPoints = TRUE, 
           pointSize = 3, color=rgb(69/255,136/255,51/255)) %>% 
  dyRangeSelector()

Team members countries total cases:

COVID_2_Day_Lebanon<- COVID_2 %>% 
  filter(Country.Region %in% c("Lebanon")) %>% 
  group_by(Date2) %>% summarise(World_confirmed=sum(Confirmed))

COVID_2_Day_Chile<- COVID_2 %>% 
  filter(Country.Region %in% c("Chile")) %>% 
  group_by(Date2) %>% summarise(World_confirmed=sum(Confirmed))

COVID_2_Day_Colombia<- COVID_2 %>% 
  filter(Country.Region %in% c("Colombia")) %>% 
  group_by(Date2) %>% summarise(World_confirmed=sum(Confirmed))

COVID_2_Day_CostaRica<- COVID_2 %>% 
  filter(Country.Region %in% c("Costa Rica")) %>% 
  group_by(Date2) %>% summarise(World_confirmed=sum(Confirmed))


COVID_Day_series_Lebanon<-xts(COVID_2_Day_Lebanon$World_confirmed, order.by=COVID_2_Day_Lebanon$Date2)
COVID_Day_series_Chile<-xts(COVID_2_Day_Chile$World_confirmed, order.by=COVID_2_Day_Chile$Date2)
COVID_Day_series_Colombia<-xts(COVID_2_Day_Colombia$World_confirmed, order.by=COVID_2_Day_Colombia$Date2)
COVID_Day_series_CostaRica<-xts(COVID_2_Day_CostaRica$World_confirmed, order.by=COVID_2_Day_CostaRica$Date2)

Our_Countries<-cbind(COVID_Day_series_Lebanon,COVID_Day_series_Chile,COVID_Day_series_Colombia,COVID_Day_series_CostaRica)
dygraph(Our_Countries, main = "SARS-COV2-outbreak: Total cases by country", xlab="Date", ylab="Total cases",width = 750) %>% 
  dySeries("COVID_Day_series_Lebanon", "Lebanon",drawPoints = TRUE, 
           pointSize = 3, color=rgb(0,0,3/255)) %>% 
  dySeries("COVID_Day_series_Chile", "Chile",drawPoints = TRUE, 
           pointSize = 3,color=rgb(120/255,28/255,109/255)) %>% 
  dySeries("COVID_Day_series_Colombia", "Colombia",drawPoints = TRUE, 
           pointSize = 3,color=rgb(237/255,105/255,37/255)) %>% 
  dySeries("COVID_Day_series_CostaRica", "Costa Rica",drawPoints = TRUE,
           pointSize = 3,color=rgb(204/255,197/255,126/255)) %>% 
  dyRangeSelector()

Looking for correlations

fig <- plot_ly(COVID_updated, x = ~Confirmed, y = ~Deaths, z = ~Recovered, width=750) %>% 
  add_markers(text= ~Country.Region ,hoverinfo= "text",
              marker = list(color=rgb(189/255,55/255,48/255))) %>% 
  layout(title="Confirmed cases Vs. Deaths Vs. Recovered", scene = list(
                    xaxis = list(title = 'Confirmed'),
                     yaxis = list(title = 'Deaths'),
                     zaxis = list(title = 'Recovered'))) 
fig

Human Development Index

HDI<-read.csv("Human Development Index (HDI)_2.csv",sep=";",dec=",")
COVID_Country<-COVID_2 %>% filter(Date2==max(Date2)) %>% 
  group_by(Country.Region) %>% summarise(Total_confirmed=sum(Confirmed),
                                         Total_deaths=sum(Deaths),
                                         Total_Recovered=sum(Recovered))

Remove after parentheses:

HDI$Country_2<-gsub("\\s*\\([^\\)]+\\)","",as.character(HDI$Country))
HDI$Country_2[HDI$Country_2=="United States"]<-"US"
HDI$Country_2[HDI$Country_2=="Korea"]<-"South Korea"

Population:

Population<-read.csv("World_population.csv",sep=";",dec=",")

Remove after commma:

Population$Country_Name_2<-gsub(",.*", "", as.character(Population$Country_Name))
Population$Country_Name_2[Population$Country_Name_2=="United States"]<-"US"
Population$Country_Name_2[Population$Country_Code=="KOR"]<-"South Korea"
Population$Country_Name_2[Population$Country_Code=="CZE"]<-"Czechia"

Natural Join:

COVID_3<- COVID_Country %>% inner_join(HDI,by=c("Country.Region"="Country_2")) %>% 
  inner_join(Population,by=c("Country.Region"="Country_Name_2")) %>% 
  select(Country.Region,Total_confirmed,Total_deaths,Total_Recovered,HDI_Rank_2018,Year_2018,
         Country_Code,Population_2018) %>% 
  mutate(Cases_million=(Total_confirmed/Population_2018)*1000000,
         Recovered_percentage=(Total_Recovered/Total_confirmed)*100)  

COVID_3<-COVID_3[!is.na(COVID_3$Population_2018),]

#write.csv(COVID_3,"COVID_HDI.csv")

Plot the Human Development Index(HDI) Vs. the number of cases (applying a log transformation), and the proportion of recovered cases:

plot<-ggplot(data=COVID_3,aes(x=log(Cases_million),y=Year_2018,
                        size=Recovered_percentage,text=Country.Region)) +
  geom_point(color="black",fill=rgb(237/255,105/255,37/255),shape=21,alpha=0.6) +
  scale_size(range = c(3,15), name="Recovered \n percentage") +
  theme_minimal() + 
  theme(legend.position="bottom") +
  labs(title="HDI Vs. logarithmus of COVID-19 cases by million inhabitants \n and proportion of recovered",
       x="ln(Cases/1M population)",
       y="HDI")

ggplotly(plot,tooltip = c("text"),width=750)
COVID_numeric_1<-COVID_3 %>% mutate(Log_cases=log(Cases_million),
                                    Death_percentage=(Total_deaths/Total_confirmed)*100) %>% 
  select(Log_cases,Recovered_percentage,Death_percentage,Year_2018)

corrplot(cor(COVID_numeric_1),method = "number",tl.col="black",tl.srt=15,
         col=colorRampPalette(c(rgb(204/255,197/255,126/255),rgb(237/255,105/255,37/255)))(200))

LS0tCnRpdGxlOiAiQ09WSUQtMTkgT3V0YnJlYWs6IFdvcmxkd2lkZSBhbmFseXNpcyIKYXV0aG9yOiAiQW91biwgQ2FtYXJnbywgTWFydGluZXosUm9kcmlndWV6IgpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHRydWUKICAgIHRvY19kZXB0aDogMwogICAgdG9jX2Zsb2F0OgogICAgICBjb2xsYXBzZWQ6IHRydWUKICAgICAgc21vb3RoX3Njcm9sbDogdHJ1ZQogICAgdGhlbWU6IGNvc21vCiAgICAgCi0tLQohW10oQ29yb25hdmlydXMuanBnKQoKIyBRdWljayBvdmVydmlldwoKIyMgQ3VycmVudCBzdGF0dXMKCgpgYGB7cixtZXNzYWdlPUZBTFNFLHdhcm5pbmc9RkFMU0V9CiNsaWJyYXJ5KG5Db3YyMDE5KQpsaWJyYXJ5KGxlYWZsZXQpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShwbG90bHkpCmxpYnJhcnkoc2NhbGVzKQpsaWJyYXJ5KHh0cykKbGlicmFyeShkeWdyYXBocykKbGlicmFyeShjb3JycGxvdCkKYGBgCgpgYGB7cn0KQ09WSUQ8LXJlYWQuY3N2KCJjb3ZpZF8xOV9kYXRhLmNzdiIpCkNPVklEXzI8LXJlYWQuY3N2KCJDT1ZJRDE5XzctQXByLmNzdiIpCmBgYAoKRm9ybWF0IGRhdGU6CmBgYHtyfQpEYXRlPC1hcy5EYXRlKENPVklEXzIkRGF0ZSwgZm9ybWF0PSIlbS8lZC8leSIpIAoKQ09WSURfMiREYXRlMjwtRGF0ZQpgYGAKCmBgYHtyfQpDT1ZJRF91cGRhdGVkPC1DT1ZJRF8yICU+JSBmaWx0ZXIoRGF0ZTI9PW1heChEYXRlMikpCmBgYAoKYGBge3J9CmxlYWZsZXQod2lkdGggPSAiMTAwJSIpICU+JSAKICBhZGRQcm92aWRlclRpbGVzKCJDYXJ0b0RCLkRhcmtNYXR0ZXIiKSAlPiUgCiAgc2V0VmlldyhsbmcgPSAwLCBsYXQgPSAxMCwgem9vbSA9IDEuNSkgJT4lIAogIGFkZENpcmNsZU1hcmtlcnMoZGF0YSA9IENPVklEX3VwZGF0ZWQsIAogICAgICAgICAgICAgICAgICAgbG5nID0gfiBMb25nLAogICAgICAgICAgICAgICAgICAgbGF0ID0gfiBMYXQsCiAgICAgICAgICAgICAgICAgICByYWRpdXMgPSB+IGxvZyhDb25maXJtZWQrMSksCiAgICAgICAgICAgICAgICAgICBjb2xvciA9IHJnYigyMTgvMjU1LDY1LzI1NSw1Ni8yNTUpLAogICAgICAgICAgICAgICAgICAgZmlsbE9wYWNpdHkgPSB+IGlmZWxzZShDb25maXJtZWQgPiAwLCAxLCAwKSwKICAgICAgICAgICAgICAgICAgIHN0cm9rZSA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgbGFiZWwgPSB+IHBhc3RlKFByb3ZpbmNlLlN0YXRlLCIsIixDb3VudHJ5LlJlZ2lvbiwgIjogIiwgQ29uZmlybWVkKQogICAgICAgICAgICAgICAgICAgKQpgYGAKCkN1cnJlbnQgdG9wIDEwIGNvdW50cmllczoKYGBge3J9CkNPVklEX3RvcDwtQ09WSURfMiAlPiUgZmlsdGVyKERhdGUyPT1tYXgoRGF0ZTIpKSAlPiUgCiAgZ3JvdXBfYnkoQ291bnRyeS5SZWdpb24pICU+JSBzdW1tYXJpc2UoVG90YWxfY29uZmlybWVkPXN1bShDb25maXJtZWQpKSAlPiUgCiAgdG9wX24oMTAsVG90YWxfY29uZmlybWVkKSAlPiUgYXJyYW5nZShkZXNjKFRvdGFsX2NvbmZpcm1lZCkpCmBgYAoKYGBge3J9CnBsb3Q8LWdncGxvdChkYXRhPUNPVklEX3RvcAogICAgICAgLCBhZXMoeD1Ub3RhbF9jb25maXJtZWQseT1yZW9yZGVyKENvdW50cnkuUmVnaW9uLFRvdGFsX2NvbmZpcm1lZCkpKSArCiAgZ2VvbV9iYXIoc3RhdCA9ImlkZW50aXR5IixhbHBoYT0wLjgsZmlsbD0iZmlyZWJyaWNrMyIpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsPVRvdGFsX2NvbmZpcm1lZCksIHZqdXN0PTAuNSwgaGp1c3Q9MC45LGNvbG9yPSJibGFjayIsIHNpemU9My41KSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IGNvbW1hKSArCiAgbGFicyh0aXRsZSA9IHBhc3RlKCJUb3AgMTAgY291bnRyaWVzIHdpdGggY29uZmlybWVkIGNhc2VzIGFzIG9mICIsbWF4KENPVklEXzIkRGF0ZTIpKSwKICAgICAgIHggPSAiQ29uZmlybWVkIGNhc2VzIiwKICAgICAgIHkgPSAiQ291bnRyeSIpICsKICB0aGVtZV9taW5pbWFsKCkKCmdncGxvdGx5KHBsb3QsdG9vbHRpcCA9IGMoIngiKSx3aWR0aD03NTApCmBgYAoKVGltZSBkaXN0cmlidXRpb246CmBgYHtyfQpDT1ZJRF8yX0RheTwtIENPVklEXzIgJT4lIGdyb3VwX2J5KERhdGUyKSAlPiUgc3VtbWFyaXNlKFdvcmxkX2NvbmZpcm1lZD1zdW0oQ29uZmlybWVkKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXb3JsZF9kZWF0aHM9c3VtKERlYXRocyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV29ybGRfcmVjb3ZlcmVkPXN1bShSZWNvdmVyZWQpKQoKCkNPVklEX0RheV9jb25maXJtZWRfc2VyaWVzPC14dHMoQ09WSURfMl9EYXkkV29ybGRfY29uZmlybWVkLCBvcmRlci5ieT1DT1ZJRF8yX0RheSREYXRlMikKQ09WSURfRGF5X2RlYXRoc19zZXJpZXM8LXh0cyhDT1ZJRF8yX0RheSRXb3JsZF9kZWF0aHMsIG9yZGVyLmJ5PUNPVklEXzJfRGF5JERhdGUyKQpDT1ZJRF9EYXlfcmVjb3ZlcmVkX3NlcmllczwteHRzKENPVklEXzJfRGF5JFdvcmxkX3JlY292ZXJlZCwgb3JkZXIuYnk9Q09WSURfMl9EYXkkRGF0ZTIpCgpEYXlfc3VtbWFyeTwtY2JpbmQoQ09WSURfRGF5X2NvbmZpcm1lZF9zZXJpZXMsQ09WSURfRGF5X2RlYXRoc19zZXJpZXMsQ09WSURfRGF5X3JlY292ZXJlZF9zZXJpZXMpCmBgYAoKCmBgYHtyfQpkeWdyYXBoKERheV9zdW1tYXJ5LCBtYWluID0gIlNBUlMtQ09WMi1vdXRicmVhazogVG90YWwgd29ybGR3aWRlIGNhc2VzIiwgCiAgICAgICAgeGxhYj0iRGF0ZSIsIHlsYWI9IlRvdGFsIGNhc2VzIix3aWR0aCA9IDc1MCkgJT4lIAogIGR5U2VyaWVzKCJDT1ZJRF9EYXlfY29uZmlybWVkX3NlcmllcyIsICJUb3RhbCBjYXNlcyIsZHJhd1BvaW50cyA9IFRSVUUsIAogICAgICAgICAgIHBvaW50U2l6ZSA9IDMsIGNvbG9yPXJnYig1My8yNTUsMTE2LzI1NSwxOTkvMjU1KSkgJT4lIAogIGR5U2VyaWVzKCJDT1ZJRF9EYXlfZGVhdGhzX3NlcmllcyIsICJUb3RhbCBkZWF0aHMiLGRyYXdQb2ludHMgPSBUUlVFLCAKICAgICAgICAgICBwb2ludFNpemUgPSAzLCBjb2xvcj1yZ2IoMTg5LzI1NSw1NS8yNTUsNDgvMjU1KSkgJT4lIAogIGR5U2VyaWVzKCJDT1ZJRF9EYXlfcmVjb3ZlcmVkX3NlcmllcyIsICJUb3RhbCByZWNvdmVyZWQiLGRyYXdQb2ludHMgPSBUUlVFLCAKICAgICAgICAgICBwb2ludFNpemUgPSAzLCBjb2xvcj1yZ2IoNjkvMjU1LDEzNi8yNTUsNTEvMjU1KSkgJT4lIAogIGR5UmFuZ2VTZWxlY3RvcigpCmBgYAoKClRlYW0gbWVtYmVycyBjb3VudHJpZXMgdG90YWwgY2FzZXM6CmBgYHtyfQpDT1ZJRF8yX0RheV9MZWJhbm9uPC0gQ09WSURfMiAlPiUgCiAgZmlsdGVyKENvdW50cnkuUmVnaW9uICVpbiUgYygiTGViYW5vbiIpKSAlPiUgCiAgZ3JvdXBfYnkoRGF0ZTIpICU+JSBzdW1tYXJpc2UoV29ybGRfY29uZmlybWVkPXN1bShDb25maXJtZWQpKQoKQ09WSURfMl9EYXlfQ2hpbGU8LSBDT1ZJRF8yICU+JSAKICBmaWx0ZXIoQ291bnRyeS5SZWdpb24gJWluJSBjKCJDaGlsZSIpKSAlPiUgCiAgZ3JvdXBfYnkoRGF0ZTIpICU+JSBzdW1tYXJpc2UoV29ybGRfY29uZmlybWVkPXN1bShDb25maXJtZWQpKQoKQ09WSURfMl9EYXlfQ29sb21iaWE8LSBDT1ZJRF8yICU+JSAKICBmaWx0ZXIoQ291bnRyeS5SZWdpb24gJWluJSBjKCJDb2xvbWJpYSIpKSAlPiUgCiAgZ3JvdXBfYnkoRGF0ZTIpICU+JSBzdW1tYXJpc2UoV29ybGRfY29uZmlybWVkPXN1bShDb25maXJtZWQpKQoKQ09WSURfMl9EYXlfQ29zdGFSaWNhPC0gQ09WSURfMiAlPiUgCiAgZmlsdGVyKENvdW50cnkuUmVnaW9uICVpbiUgYygiQ29zdGEgUmljYSIpKSAlPiUgCiAgZ3JvdXBfYnkoRGF0ZTIpICU+JSBzdW1tYXJpc2UoV29ybGRfY29uZmlybWVkPXN1bShDb25maXJtZWQpKQoKCkNPVklEX0RheV9zZXJpZXNfTGViYW5vbjwteHRzKENPVklEXzJfRGF5X0xlYmFub24kV29ybGRfY29uZmlybWVkLCBvcmRlci5ieT1DT1ZJRF8yX0RheV9MZWJhbm9uJERhdGUyKQpDT1ZJRF9EYXlfc2VyaWVzX0NoaWxlPC14dHMoQ09WSURfMl9EYXlfQ2hpbGUkV29ybGRfY29uZmlybWVkLCBvcmRlci5ieT1DT1ZJRF8yX0RheV9DaGlsZSREYXRlMikKQ09WSURfRGF5X3Nlcmllc19Db2xvbWJpYTwteHRzKENPVklEXzJfRGF5X0NvbG9tYmlhJFdvcmxkX2NvbmZpcm1lZCwgb3JkZXIuYnk9Q09WSURfMl9EYXlfQ29sb21iaWEkRGF0ZTIpCkNPVklEX0RheV9zZXJpZXNfQ29zdGFSaWNhPC14dHMoQ09WSURfMl9EYXlfQ29zdGFSaWNhJFdvcmxkX2NvbmZpcm1lZCwgb3JkZXIuYnk9Q09WSURfMl9EYXlfQ29zdGFSaWNhJERhdGUyKQoKT3VyX0NvdW50cmllczwtY2JpbmQoQ09WSURfRGF5X3Nlcmllc19MZWJhbm9uLENPVklEX0RheV9zZXJpZXNfQ2hpbGUsQ09WSURfRGF5X3Nlcmllc19Db2xvbWJpYSxDT1ZJRF9EYXlfc2VyaWVzX0Nvc3RhUmljYSkKCmBgYAoKYGBge3J9CmR5Z3JhcGgoT3VyX0NvdW50cmllcywgbWFpbiA9ICJTQVJTLUNPVjItb3V0YnJlYWs6IFRvdGFsIGNhc2VzIGJ5IGNvdW50cnkiLCB4bGFiPSJEYXRlIiwgeWxhYj0iVG90YWwgY2FzZXMiLHdpZHRoID0gNzUwKSAlPiUgCiAgZHlTZXJpZXMoIkNPVklEX0RheV9zZXJpZXNfTGViYW5vbiIsICJMZWJhbm9uIixkcmF3UG9pbnRzID0gVFJVRSwgCiAgICAgICAgICAgcG9pbnRTaXplID0gMywgY29sb3I9cmdiKDAsMCwzLzI1NSkpICU+JSAKICBkeVNlcmllcygiQ09WSURfRGF5X3Nlcmllc19DaGlsZSIsICJDaGlsZSIsZHJhd1BvaW50cyA9IFRSVUUsIAogICAgICAgICAgIHBvaW50U2l6ZSA9IDMsY29sb3I9cmdiKDEyMC8yNTUsMjgvMjU1LDEwOS8yNTUpKSAlPiUgCiAgZHlTZXJpZXMoIkNPVklEX0RheV9zZXJpZXNfQ29sb21iaWEiLCAiQ29sb21iaWEiLGRyYXdQb2ludHMgPSBUUlVFLCAKICAgICAgICAgICBwb2ludFNpemUgPSAzLGNvbG9yPXJnYigyMzcvMjU1LDEwNS8yNTUsMzcvMjU1KSkgJT4lIAogIGR5U2VyaWVzKCJDT1ZJRF9EYXlfc2VyaWVzX0Nvc3RhUmljYSIsICJDb3N0YSBSaWNhIixkcmF3UG9pbnRzID0gVFJVRSwKICAgICAgICAgICBwb2ludFNpemUgPSAzLGNvbG9yPXJnYigyMDQvMjU1LDE5Ny8yNTUsMTI2LzI1NSkpICU+JSAKICBkeVJhbmdlU2VsZWN0b3IoKQpgYGAKCgojIExvb2tpbmcgZm9yIGNvcnJlbGF0aW9ucwoKYGBge3J9CmZpZyA8LSBwbG90X2x5KENPVklEX3VwZGF0ZWQsIHggPSB+Q29uZmlybWVkLCB5ID0gfkRlYXRocywgeiA9IH5SZWNvdmVyZWQsIHdpZHRoPTc1MCkgJT4lIAogIGFkZF9tYXJrZXJzKHRleHQ9IH5Db3VudHJ5LlJlZ2lvbiAsaG92ZXJpbmZvPSAidGV4dCIsCiAgICAgICAgICAgICAgbWFya2VyID0gbGlzdChjb2xvcj1yZ2IoMTg5LzI1NSw1NS8yNTUsNDgvMjU1KSkpICU+JSAKICBsYXlvdXQodGl0bGU9IkNvbmZpcm1lZCBjYXNlcyBWcy4gRGVhdGhzIFZzLiBSZWNvdmVyZWQiLCBzY2VuZSA9IGxpc3QoCiAgICAgICAgICAgICAgICAgICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gJ0NvbmZpcm1lZCcpLAogICAgICAgICAgICAgICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAnRGVhdGhzJyksCiAgICAgICAgICAgICAgICAgICAgIHpheGlzID0gbGlzdCh0aXRsZSA9ICdSZWNvdmVyZWQnKSkpIApmaWcKYGBgCgojIyBIdW1hbiBEZXZlbG9wbWVudCBJbmRleAoKYGBge3J9CkhESTwtcmVhZC5jc3YoIkh1bWFuIERldmVsb3BtZW50IEluZGV4IChIREkpXzIuY3N2IixzZXA9IjsiLGRlYz0iLCIpCmBgYAoKYGBge3J9CkNPVklEX0NvdW50cnk8LUNPVklEXzIgJT4lIGZpbHRlcihEYXRlMj09bWF4KERhdGUyKSkgJT4lIAogIGdyb3VwX2J5KENvdW50cnkuUmVnaW9uKSAlPiUgc3VtbWFyaXNlKFRvdGFsX2NvbmZpcm1lZD1zdW0oQ29uZmlybWVkKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUb3RhbF9kZWF0aHM9c3VtKERlYXRocyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVG90YWxfUmVjb3ZlcmVkPXN1bShSZWNvdmVyZWQpKQpgYGAKClJlbW92ZSBhZnRlciBwYXJlbnRoZXNlczoKYGBge3J9CkhESSRDb3VudHJ5XzI8LWdzdWIoIlxccypcXChbXlxcKV0rXFwpIiwiIixhcy5jaGFyYWN0ZXIoSERJJENvdW50cnkpKQpgYGAKCmBgYHtyfQpIREkkQ291bnRyeV8yW0hESSRDb3VudHJ5XzI9PSJVbml0ZWQgU3RhdGVzIl08LSJVUyIKSERJJENvdW50cnlfMltIREkkQ291bnRyeV8yPT0iS29yZWEiXTwtIlNvdXRoIEtvcmVhIgpgYGAKClBvcHVsYXRpb246CmBgYHtyfQpQb3B1bGF0aW9uPC1yZWFkLmNzdigiV29ybGRfcG9wdWxhdGlvbi5jc3YiLHNlcD0iOyIsZGVjPSIsIikKYGBgCgpSZW1vdmUgYWZ0ZXIgY29tbW1hOgpgYGB7cn0KUG9wdWxhdGlvbiRDb3VudHJ5X05hbWVfMjwtZ3N1YigiLC4qIiwgIiIsIGFzLmNoYXJhY3RlcihQb3B1bGF0aW9uJENvdW50cnlfTmFtZSkpCmBgYAoKYGBge3J9ClBvcHVsYXRpb24kQ291bnRyeV9OYW1lXzJbUG9wdWxhdGlvbiRDb3VudHJ5X05hbWVfMj09IlVuaXRlZCBTdGF0ZXMiXTwtIlVTIgpQb3B1bGF0aW9uJENvdW50cnlfTmFtZV8yW1BvcHVsYXRpb24kQ291bnRyeV9Db2RlPT0iS09SIl08LSJTb3V0aCBLb3JlYSIKUG9wdWxhdGlvbiRDb3VudHJ5X05hbWVfMltQb3B1bGF0aW9uJENvdW50cnlfQ29kZT09IkNaRSJdPC0iQ3plY2hpYSIKYGBgCgpOYXR1cmFsIEpvaW46CmBgYHtyLHdhcm5pbmc9RkFMU0UsbWVzc2FnZT1GQUxTRX0KQ09WSURfMzwtIENPVklEX0NvdW50cnkgJT4lIGlubmVyX2pvaW4oSERJLGJ5PWMoIkNvdW50cnkuUmVnaW9uIj0iQ291bnRyeV8yIikpICU+JSAKICBpbm5lcl9qb2luKFBvcHVsYXRpb24sYnk9YygiQ291bnRyeS5SZWdpb24iPSJDb3VudHJ5X05hbWVfMiIpKSAlPiUgCiAgc2VsZWN0KENvdW50cnkuUmVnaW9uLFRvdGFsX2NvbmZpcm1lZCxUb3RhbF9kZWF0aHMsVG90YWxfUmVjb3ZlcmVkLEhESV9SYW5rXzIwMTgsWWVhcl8yMDE4LAogICAgICAgICBDb3VudHJ5X0NvZGUsUG9wdWxhdGlvbl8yMDE4KSAlPiUgCiAgbXV0YXRlKENhc2VzX21pbGxpb249KFRvdGFsX2NvbmZpcm1lZC9Qb3B1bGF0aW9uXzIwMTgpKjEwMDAwMDAsCiAgICAgICAgIFJlY292ZXJlZF9wZXJjZW50YWdlPShUb3RhbF9SZWNvdmVyZWQvVG90YWxfY29uZmlybWVkKSoxMDApICAKCkNPVklEXzM8LUNPVklEXzNbIWlzLm5hKENPVklEXzMkUG9wdWxhdGlvbl8yMDE4KSxdCgojd3JpdGUuY3N2KENPVklEXzMsIkNPVklEX0hESS5jc3YiKQpgYGAKClBsb3QgdGhlIEh1bWFuIERldmVsb3BtZW50IEluZGV4KEhESSkgVnMuIHRoZSBudW1iZXIgb2YgY2FzZXMgKGFwcGx5aW5nIGEgbG9nIHRyYW5zZm9ybWF0aW9uKSwgYW5kIHRoZSBwcm9wb3J0aW9uIG9mIHJlY292ZXJlZCBjYXNlczoKYGBge3J9CnBsb3Q8LWdncGxvdChkYXRhPUNPVklEXzMsYWVzKHg9bG9nKENhc2VzX21pbGxpb24pLHk9WWVhcl8yMDE4LAogICAgICAgICAgICAgICAgICAgICAgICBzaXplPVJlY292ZXJlZF9wZXJjZW50YWdlLHRleHQ9Q291bnRyeS5SZWdpb24pKSArCiAgZ2VvbV9wb2ludChjb2xvcj0iYmxhY2siLGZpbGw9cmdiKDIzNy8yNTUsMTA1LzI1NSwzNy8yNTUpLHNoYXBlPTIxLGFscGhhPTAuNikgKwogIHNjYWxlX3NpemUocmFuZ2UgPSBjKDMsMTUpLCBuYW1lPSJSZWNvdmVyZWQgXG4gcGVyY2VudGFnZSIpICsKICB0aGVtZV9taW5pbWFsKCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb249ImJvdHRvbSIpICsKICBsYWJzKHRpdGxlPSJIREkgVnMuIGxvZ2FyaXRobXVzIG9mIENPVklELTE5IGNhc2VzIGJ5IG1pbGxpb24gaW5oYWJpdGFudHMgXG4gYW5kIHByb3BvcnRpb24gb2YgcmVjb3ZlcmVkIiwKICAgICAgIHg9ImxuKENhc2VzLzFNIHBvcHVsYXRpb24pIiwKICAgICAgIHk9IkhESSIpCgpnZ3Bsb3RseShwbG90LHRvb2x0aXAgPSBjKCJ0ZXh0Iiksd2lkdGg9NzUwKQpgYGAKCgpgYGB7cn0KQ09WSURfbnVtZXJpY18xPC1DT1ZJRF8zICU+JSBtdXRhdGUoTG9nX2Nhc2VzPWxvZyhDYXNlc19taWxsaW9uKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVhdGhfcGVyY2VudGFnZT0oVG90YWxfZGVhdGhzL1RvdGFsX2NvbmZpcm1lZCkqMTAwKSAlPiUgCiAgc2VsZWN0KExvZ19jYXNlcyxSZWNvdmVyZWRfcGVyY2VudGFnZSxEZWF0aF9wZXJjZW50YWdlLFllYXJfMjAxOCkKCmNvcnJwbG90KGNvcihDT1ZJRF9udW1lcmljXzEpLG1ldGhvZCA9ICJudW1iZXIiLHRsLmNvbD0iYmxhY2siLHRsLnNydD0xNSwKICAgICAgICAgY29sPWNvbG9yUmFtcFBhbGV0dGUoYyhyZ2IoMjA0LzI1NSwxOTcvMjU1LDEyNi8yNTUpLHJnYigyMzcvMjU1LDEwNS8yNTUsMzcvMjU1KSkpKDIwMCkpCmBgYAoKCgoKCgoKCgoK